/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: WeChatChannelProxy
 * Author:   zhouheng
 * Date:     2019/5/15 11:44
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.star.pay.service.core.processor.channel.wechat;

import com.star.pay.service.core.bean.UnifiedOrderBean;
import com.star.pay.service.core.common.HttpClientUtil;
import com.star.pay.service.core.common.PayChannelEnum;
import com.star.pay.service.core.common.PaymentConstants;
import com.star.pay.service.core.common.PaymentResponseEnum;
import com.star.pay.service.core.config.PaymentConfig;
import com.star.pay.service.core.processor.channel.BasePayChannelProxy;
import com.star.pay.service.core.processor.context.PaymentContext;
import com.star.pay.service.core.processor.context.WeChatPayContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 〈一句话功能简述〉<br> 
 * 〈〉
 *
 * @author zhouheng
 * @create 2019/5/15
 * @since 1.0.0
 */
@Slf4j
@Component
public class WeChatChannelProxy extends BasePayChannelProxy {

    @Autowired
    PaymentConfig paymentConfig;

    @Override
    public String getPayChannel() {
        return PayChannelEnum.WECHAT_PAY.getCode();
    }

    @Override
    public boolean preCheck(PaymentContext paymentContext) {
        WeChatPayContext weChatPayContext = (WeChatPayContext) paymentContext;
        if (StringUtils.isBlank(weChatPayContext.getBody())) {
            paymentContext.setResCode(PaymentResponseEnum.SYS_PARAM_NOT_RIGHT, "商品描述不能为空");
            return false;
        }
        if (StringUtils.isBlank(weChatPayContext.getOutTradeNo())) {
            paymentContext.setResCode(PaymentResponseEnum.SYS_PARAM_NOT_RIGHT, "商户订单号不能为空");
            return false;
        }
        if (StringUtils.isBlank(weChatPayContext.getTradeType())) {
            paymentContext.setResCode(PaymentResponseEnum.SYS_PARAM_NOT_RIGHT, "交易类型不能为空");
            return false;
        }
        if (weChatPayContext.getTotalFee() == null) {
            paymentContext.setResCode(PaymentResponseEnum.SYS_PARAM_NOT_RIGHT, "支付总金额不能为空");
            return false;
        }
        if (StringUtils.isBlank(weChatPayContext.getSpbillCreateIp())) {
            paymentContext.setResCode(PaymentResponseEnum.SYS_PARAM_NOT_RIGHT, "终端ip不能为空");
            return false;
        }
        if (PaymentConstants.TradeTypeEnum.JSAPI.getType().equals(weChatPayContext.getTradeType())) {
            if (StringUtils.isBlank(weChatPayContext.getOpenid())) {
                paymentContext.setResCode(PaymentResponseEnum.SYS_PARAM_NOT_RIGHT, "交易类型不能为空");
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean paymentProcess(PaymentContext paymentContext) {
        WeChatPayContext context = (WeChatPayContext) paymentContext;
        //step1 调用微信商户统一下单接口
        try {
            SortedMap<Object, Object> paraMap = new TreeMap<Object, Object>();
            paraMap.put("body", context.getBody());
            paraMap.put("out_trade_no", context.getOutTradeNo());
            paraMap.put("total_fee", context.getTotalFee().intValue());//单位分
            paraMap.put("spbill_create_ip", context.getSpbillCreateIp());
            paraMap.put("appid", paymentConfig.getWechatAppid());
            paraMap.put("mch_id", paymentConfig.getWechatMch_id());
            paraMap.put("nonce_str", WeChatRequest.getNonceStr());
            paraMap.put("trade_type", context.getTradeType());
            paraMap.put("product_id",context.getProductId());
            paraMap.put("device_info","WEB");
            paraMap.put("notify_url", paymentConfig.getWechatNotifyurl());// 此路径是微信服务器调用支付结果通知路径
            String sign = WeChatRequest.createSign(paraMap, paymentConfig.getWechatMchsecret());
            paraMap.put("sign", sign);
            String xml = WeChatRequest.getRequestXml(paraMap);
            String xmlStr = HttpClientUtil.httpPost(paymentConfig.getWechatUnifiedOrder(), xml);
            log.info("【微信支付落单】下单返回结果：" + xmlStr);
            Map<String, String> resultMap = WeChatRequest.doXMLParse(xmlStr);
            if ("SUCCESS".equals(resultMap.get("return_code"))) {
                if ("SUCCESS".equals(resultMap.get("result_code"))) {
                    //表示订单处理成功
                    UnifiedOrderBean unifiedOrderBean = new UnifiedOrderBean();
                    unifiedOrderBean.setPrepay_id(resultMap.get("prepay_id"));
                    unifiedOrderBean.setCode_url(resultMap.get("code_url"));
                    context.setUnifiedOrderBean(unifiedOrderBean);
                    context.setResCode(PaymentResponseEnum.SUCCESS, "");
                    return true;
                } else {
                    String errMsg = resultMap.get("err_code") + ":" + resultMap.get("err_code_des");
                    context.setResCode(PaymentResponseEnum.PAYMENT_PROCESSOR_FAILED, errMsg);
                    return false;
                }
            } else {
                context.setResCode(PaymentResponseEnum.PAYMENT_PROCESSOR_FAILED, resultMap.get("return_msg"));
                return false;
            }
        } catch (Exception e){
            log.error("【微信支付落单】异常{}", context.getOutTradeNo());
            return false;
        }
    }
}